package org.apache.oozie.tools.workflowgenerator.client.property.action;

import java.util.ArrayList;
import java.util.List;

import org.apache.oozie.tools.workflowgenerator.client.property.PropertyTable;
import org.apache.oozie.tools.workflowgenerator.client.widget.NodeWidget;

import com.google.gwt.cell.client.ButtonCell;
import com.google.gwt.cell.client.FieldUpdater;
import com.google.gwt.cell.client.TextInputCell;
import com.google.gwt.xml.client.Text;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.RadioButton;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.xml.client.Document;
import com.google.gwt.xml.client.Element;

public class SSHPropertyTable extends PropertyTable {

    protected Grid grid;
    protected List<String> args;
    protected TextBox host;
    protected TextBox command;
    protected RadioButton rby;
    protected RadioButton rbn;

    public SSHPropertyTable(NodeWidget w) {
        super(w);
        initConf();
        initWidget();
    }

    /**
     * Initialize configuration
     */
    protected void initConf() {
        args = new ArrayList<String>();
        args.add("");

        widgetList = new ArrayList<NodeWidget>();
        updateWidgetList();
        widgetDropDown = new ArrayList<NodeWidget>();
        updateWidgetDropDown();
    }

    /**
     * Generate xml elements of ssh action and attach them to xml doc
     */
    public void generateXML(Document doc, Element root, NodeWidget next) {

        Element action = doc.createElement("action");
        action.setAttribute("name", current.getName());

        // create <ssh>
        Element sshele = doc.createElement("ssh");
        action.appendChild(sshele);

        // create <host>
        Element hostele = doc.createElement("host");
        Text t = doc.createTextNode(host.getText());
        hostele.appendChild(t);
        sshele.appendChild(hostele);

        // create <command>
        Element commandele = doc.createElement("command");
        Text x = doc.createTextNode(command.getText());
        commandele.appendChild(x);
        sshele.appendChild(commandele);

        // create <args>
        for (String arg : args) {
            Element argsele = doc.createElement("args");
            Text n = doc.createTextNode(arg);
            argsele.appendChild(n);
            sshele.appendChild(argsele);

        }

        // create <capture-output>
        if (rby.getValue()) {
            Element outputele = doc.createElement("capture-output");
            sshele.appendChild(outputele);
        }

        Element okele = doc.createElement("ok");
        okele.setAttribute("to", next.getName());
        action.appendChild(okele);

        Element errele = doc.createElement("error");
        NodeWidget kill = getKillNode();
        errele.setAttribute("to", kill == null ? "" : kill.getName());
        action.appendChild(errele);

        root.appendChild(action);

    }

    /**
     * initialize widgets shown in property table
     */
    protected void initWidget() {

        grid = new Grid(8, 2);
        this.add(grid);

        this.setAlwaysShowScrollBars(true);
        this.setSize("100%", "80%");

        // insert row for Name
        grid.setWidget(0, 0, createLabel("Name"));
        name = new TextBox();
        name.setText("SSH"); // default value
        grid.setWidget(0, 1, formatCell(name));

        // insert row for OK
        grid.setWidget(1, 0, createLabel("OK"));
        okVal = new ListBox();
        createWidgetDropDownList(okVal);
        grid.setWidget(1, 1, formatCell(okVal));

        // insert row for ERROR
        grid.setWidget(2, 0, createLabel("Error"));
        errorVal = new ListBox();
        updateErrorDropDownList();
        grid.setWidget(2, 1, formatCell(errorVal));

        // insert row for Host
        grid.setWidget(3, 0, createLabel("Host"));
        host = new TextBox();
        grid.setWidget(3, 1, formatCell(host));

        // insert row for Command
        grid.setWidget(4, 0, createLabel("Command"));
        command = new TextBox();
        grid.setWidget(4, 1, formatCell(command));

        // insert row for Arguments
        grid.setWidget(5, 0, createLabel("Args"));
        grid.setWidget(5, 1, createArgsTable(args));

        // insert row for Capture Output
        grid.setWidget(6, 0, createLabel("Capture Output"));
        HorizontalPanel btnpanel = new HorizontalPanel();
        btnpanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_BOTTOM);
        rbn = new RadioButton("outputGroup", "false");
        rby = new RadioButton("outputGroup", "true");
        rbn.setChecked(true);
        btnpanel.add(rby);
        btnpanel.add(rbn);
        grid.setWidget(6, 1, btnpanel);

    }

    /**
     * Create a table showing list of arguments added by a user
     *
     * @param data
     * @return
     */
    protected CellTable<String> createArgsTable(List<String> data) {
        final CellTable<String> table = new CellTable<String>();
        final ListDataProvider<String> dataProvider = new ListDataProvider<String>();
        dataProvider.setList(data);
        dataProvider.addDataDisplay(table);

        // Add Name column
        Column<String, String> argCol = null;

        // when editText is used for name column

        argCol = new Column<String, String>(new TextInputCell()) {
            @Override
            public String getValue(String object) {
                return object;
            }
        };

        // set event for updating value
        argCol.setFieldUpdater(new FieldUpdater<String, String>() {
            @Override
            public void update(int index, String object, String value) {
                List<String> li = dataProvider.getList();
                li.remove(index);
                li.add(index, value);
            }
        });
        table.addColumn(argCol, "");

        // Button to add row
        Column<String, String> addCol = new Column<String, String>(new ButtonCell()) {
            @Override
            public String getValue(String object) {
                return " + ";
            }
        };
        addCol.setFieldUpdater(new FieldUpdater<String, String>() {
            @Override
            public void update(int index, String object, String value) {
                List<String> li = dataProvider.getList();
                li.add(index + 1, new String(" "));
            }
        });

        table.addColumn(addCol, "");

        // Button to delete row
        Column<String, String> delCol = new Column<String, String>(new ButtonCell()) {
            @Override
            public String getValue(String object) {
                return " - ";
            }
        };

        delCol.setFieldUpdater(new FieldUpdater<String, String>() {
            @Override
            public void update(int index, String object, String value) {
                List<String> li = dataProvider.getList();
                li.remove(index);
                if (li.size() == 0) {
                    li.add(" ");
                    table.redraw();
                }
            }
        });

        table.addColumn(delCol, "");

        return table;

    }
}
